package com.cuit.zuke.hotel.service.impl;

import com.alibaba.fastjson.JSON;
import com.cuit.zuke.common.util.Result;
import com.cuit.zuke.hotel.client.DictFeignClient;
import com.cuit.zuke.hotel.model.hotel.HotelRoom;
import com.cuit.zuke.hotel.repository.HotelRepository;
import com.cuit.zuke.hotel.service.HotelRoomService;
import com.cuit.zuke.hotel.service.HotelService;
import com.cuit.zuke.hotel.model.hotel.Hotel;
import com.cuit.zuke.hotel.vo.hotel.HotelQueryVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class HotelServiceImpl implements HotelService {

    @Autowired
    private HotelRepository hotelRepository;

    @Autowired
    private DictFeignClient dictFeignClient;

    @Autowired
    private HotelRoomService hotelRoomService;
    /**
     * date数据格式化
     * @param date 源date数据
     * @param dateFormat 目标date格式化数据
     * @return 格式化后的date数据
     */
    public static String dateToStr(Date date, String dateFormat) {
        //date为null时返回空字符串
        if (date==null) {
            return "";
        }
        //传入的时间格式不为空时
        if (!StringUtils.isEmpty(dateFormat)) {
            SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
            return sdf.format(date);
        } else {
            //传入的时间格式为空时默认格式为yyyy-MM-dd
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.format(date);
        }
    }

    /**
     * 通用set方法封装
     * @param targetHotel 数据库中查询到的酒店数据
     * @param hotel 传来的酒店数据
     * @param index 1执行更新，0执行保存
     * @return 1 or 0
     */
    private void quickSet(Hotel targetHotel,Hotel hotel,int index){
        if(index == 0){
            //0：未上线 1：已上线
            hotel.setStatus(0);
            hotel.setCreateTime(dateToStr(new Date(),"yyyy-MM-dd"));
            hotel.setUpdateTime(dateToStr(new Date(),"yyyy-MM-dd"));
            hotel.setIsDeleted(0);
            hotelRepository.save(hotel);
            List<HotelRoom> list = hotel.getHotelRoom();
            for (HotelRoom hr : list) {
                hotelRoomService.save(hr);
            }

        }else{
            hotel.setStatus(targetHotel.getStatus());
            hotel.setCreateTime(targetHotel.getCreateTime());
            hotel.setUpdateTime(dateToStr(new Date(),"yyyy-MM-dd"));
            hotel.setIsDeleted(0);
            List<HotelRoom> list = targetHotel.getHotelRoom();
            for (HotelRoom hr : list) {
                hotelRoomService.removeById(hr.getId());
            }
            List<HotelRoom> add = hotel.getHotelRoom();
            for (HotelRoom hr : add) {
                hotelRoomService.save(hr);
            }
            hotelRepository.deleteById(targetHotel.getId());
            hotelRepository.save(hotel);
        }

    }

    /**
     * 保存酒店数据
     * @param hotel 传来的酒店数据
     * @return 1 or 0
     */
    @Override
    public void save(Hotel hotel) {
        Hotel targetHotel = hotelRepository.getHotelByZkcode(hotel.getZkcode());
        if(null != targetHotel) {
            quickSet(targetHotel,hotel,1);
        } else {
            quickSet(targetHotel,hotel,0);
        }
    }

    /**
     * 根据酒店编号获取酒店实体
     * @param zkcode 酒店编号
     * @return 1 or 0
     */
    @Override
    public Hotel getByZkcode(String zkcode) {
        return hotelRepository.getHotelByZkcode(zkcode);
    }

    /**
     * 带条件分页查询酒店列表
     * @param page 当前页
     * @param limit 每页记录数
     * @param hotelQueryVo 查询条件
     * @return 符合条件的酒店数据
     */
    @Override
    public Page<Hotel> selectPage(Integer page, Integer limit, HotelQueryVo hotelQueryVo) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        // 0为第一页
        Pageable pageable = PageRequest.of(page-1, limit, sort);

        Hotel hotel = new Hotel();
        BeanUtils.copyProperties(hotelQueryVo, hotel);

        // 创建匹配器
        ExampleMatcher matcher = ExampleMatcher.matching() // 构建对象
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 改变默认字符串匹配方式：模糊查询
                .withIgnoreCase(true); // 改变默认大小写忽略方式：忽略大小写

        // 创建实例
        Example<Hotel> example = Example.of(hotel, matcher);
        Page<Hotel> pages = hotelRepository.findAll(example, pageable);
        pages.getContent().stream().forEach(item -> {
            this.packHotel(item);
        });

        return pages;
    }

    /**
     * 调用数据字典中的静态数据，封装酒店数据
     * @param hotel hotel实体数据
     * @return 封装后的hotel实体数据
     */
    private Hotel packHotel(Hotel hotel) {
        String zktype = JSON.parseObject(dictFeignClient.getName(hotel.getZktype())).getString("data");
        String provinceString = JSON.parseObject(dictFeignClient.getName(hotel.getProvinceCode())).getString("data");;
        String cityString = JSON.parseObject(dictFeignClient.getName(hotel.getCityCode())).getString("data");
        String districtString = JSON.parseObject(dictFeignClient.getName(hotel.getDistrictCode())).getString("data");

        hotel.getParam().put("zktype", zktype);
        hotel.getParam().put("fullAddress", provinceString + cityString + districtString + hotel.getAddress());
        return hotel;
    }

    /**
     * 更新状态
     * @param id id
     * @param status 状态
     * @return 1 or 0
     */
    @Override
    public void updateStatus(String id, Integer status) {
        if(status.intValue() == 0 || status.intValue() == 1) {
            Hotel hotel = hotelRepository.findById(id).get();
            hotel.setStatus(status);
            hotel.setUpdateTime(dateToStr(new Date(),"yyyy-MM-dd"));
            hotelRepository.save(hotel);
        }
    }

    /**
     * 根据 id 获取酒店
     * @param id id
     * @return 酒店数据
     */
    @Override
    public Map<String, Object> show(String id) {
        Map<String, Object> result = new HashMap<>();
        Hotel hotel = this.packHotel(hotelRepository.findById(id).get());

        // 单独处理
        result.put("hotel", hotel);
        result.put("hotelRoom", hotel.getHotelRoom());

        // 不需要重复返回
        hotel.setHotelRoom(null);
        return result;
    }

    /**
     * 根据酒店编号获取酒店名称
     * @param zkcode 酒店编号
     * @return 酒店名称
     */
    @Override
    public String getName(String zkcode) {
        Hotel hotel = hotelRepository.getHotelByZkcode(zkcode);
        if(null != hotel) {
            return hotel.getZkname();
        }
        return "";
    }

    /**
     * 根据酒店名称模糊查找酒店
     * @param zkname 酒店名称
     * @return 酒店数据
     */
    @Override
    public List<Hotel> findByZkname(String zkname) {
        return hotelRepository.findHotelByZknameLike(zkname);
    }

    /**
     * 根据酒店编号获取酒店
     * @param zkcode 酒店编号
     * @return 酒店数据
     */
    @Override
    public Hotel item(String zkcode) {
        // 酒店详情
        Hotel hotel = this.packHotel(this.getByZkcode(zkcode));
        return hotel;
    }

    /**
     * 根据zkcode和roomcode得到对应的hotel和room
     */
    public Map<String,Object> getHotelAndRoom(String zukecode,String roomcode){
        Map<String,Object> resultMap = new HashMap<>();
        Hotel hotel = hotelRepository.getHotelByZkcode(zukecode);
        resultMap.put("hotel",hotel);
        for (HotelRoom room : hotel.getHotelRoom()) {
            if (room.getRoomcode().equals(roomcode)){
                resultMap.put("room",room);
                break;
            }
        }
        return resultMap;
    }


}
